package com.ssy.lingxi.logistics.serviceimpl;


import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.logistics.api.dto.request.CommonIdRequest;
import com.ssy.lingxi.logistics.constant.Constants;
import com.ssy.lingxi.logistics.entity.Company;
import com.ssy.lingxi.logistics.entity.LogisticsOrder;
import com.ssy.lingxi.logistics.entity.LogisticsOrderDetail;
import com.ssy.lingxi.logistics.entity.LogisticsOrderLog;
import com.ssy.lingxi.logistics.jdbc.LogisticsOrderQueryHelper;
import com.ssy.lingxi.logistics.model.enums.CommonBooleanEnum;
import com.ssy.lingxi.logistics.model.enums.LogisticsOrderCreateTypeEnum;
import com.ssy.lingxi.logistics.model.enums.LogisticsOrderStatusEnum;
import com.ssy.lingxi.logistics.model.enums.OrderLogisticsTypeEnum;
import com.ssy.lingxi.logistics.model.request.*;
import com.ssy.lingxi.logistics.model.response.*;
import com.ssy.lingxi.logistics.repository.CompanyRepository;
import com.ssy.lingxi.logistics.repository.LogisticsOrderDetailRepository;
import com.ssy.lingxi.logistics.repository.LogisticsOrderLogRepository;
import com.ssy.lingxi.logistics.repository.LogisticsOrderRepository;
import com.ssy.lingxi.logistics.service.*;
import com.ssy.lingxi.logistics.util.CodeUtils;
import com.ssy.lingxi.workflow.api.model.contant.ProcessTaskStatusEnum;
import com.ssy.lingxi.workflow.api.model.vo.request.InternalProcessQueryVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleProcessDefVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleTaskCompleteVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 物流单服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2020/7/21
 */
@Slf4j
@Service
public class LogisticsOrderServiceImpl implements ILogisticsOrderService {
    @Resource
    private LogisticsOrderQueryHelper logisticsOrderQueryHelper;
    @Resource
    private LogisticsOrderRepository logisticsOrderRepository;
    @Resource
    private LogisticsOrderDetailRepository logisticsOrderDetailRepository;
    @Resource
    private LogisticsOrderLogRepository logisticsOrderLogRepository;
    @Resource
    private CompanyRepository companyRepository;
    @Resource
    private ILogisticsOrderWorkFlowService logisticsOrderWorkFlowService;
    @Resource
    private ILogisticsOrderReportService reportService;
    @Resource
    private ILogisticsOrderNotifyService notifyService;
    @Resource
    private ILogisticsOrderSyncDataService syncDataService;
    @Resource
    private ILogisticsOrderLogService logisticsOrderLogService;


    @Override
    public Wrapper<PageData<LogisticsOrderSupplierListResponse>> pageSupplierLogisticsOrder(LogisticsSubmitOrderListRequest request, UserLoginCacheDTO loginUser) {
        PageData<LogisticsOrderSubmitListResponse> pageData = logisticsOrderQueryHelper.pageSubmitLogisticsOrder(loginUser, request, Collections.emptyList());

        List<LogisticsOrderSupplierListResponse> collect = pageData.getData().stream().map(e -> {
            LogisticsOrderSupplierListResponse response = new LogisticsOrderSupplierListResponse();
            response.setId(e.getId());
            response.setLogisticsOrderNo(e.getLogisticsOrderNo());
            response.setStatus(e.getStatus());
            response.setStatusName(LogisticsOrderStatusEnum.getCodeMsg(e.getStatus()));
            response.setCompanyName(e.getCompanyName());
            response.setRelevanceOrderCode(e.getRelevanceOrderCode());
            response.setReceiverMemberName(e.getReceiverMemberName());
            response.setCreateType(e.getCreateType());
            response.setInvoicesTime(e.getInvoicesTime());
            response.setTotalCarton(e.getTotalCarton());
            response.setTotalWeight(e.getTotalWeight());
            response.setTotalVolume(e.getTotalVolume());
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageData.getTotalCount(), collect));
    }

    @Override
    public Wrapper<PageData<LogisticsOrderSubmitListResponse>> pageSubmitLogisticsOrder(LogisticsSubmitOrderListRequest request, UserLoginCacheDTO loginUser) {
        List<Integer> statusList = Arrays.asList(LogisticsOrderStatusEnum.WAIT_SUBMIT.getCode(), LogisticsOrderStatusEnum.NO_RECEIVE.getCode());
        PageData<LogisticsOrderSubmitListResponse> pageData = logisticsOrderQueryHelper.pageSubmitLogisticsOrder(loginUser, request, statusList);

        pageData.getData().forEach(e -> {
            e.setStatusName(LogisticsOrderStatusEnum.getCodeMsg(e.getStatus()));
            e.setSubmit(LogisticsOrderStatusEnum.WAIT_SUBMIT.getCode().equals(e.getStatus()));
            e.setUpdate(statusList.contains(e.getStatus()));
            e.setDelete(LogisticsOrderStatusEnum.WAIT_SUBMIT.getCode().equals(e.getStatus()));
        });
        return Wrapper.success(pageData);
    }

    @Override
    public Wrapper<PageData<LogisticsOrderHandleListResponse>> pageHandleLogisticsOrder(LogisticsHandleOrderListRequest request, UserLoginCacheDTO loginUser) {
        PageData<LogisticsOrderHandleListResponse> pageData = logisticsOrderQueryHelper.pageHandleLogisticsOrder(loginUser, request, loginUser.getMemberId());

        pageData.getData().forEach(e -> {
            e.setStatusName(LogisticsOrderStatusEnum.getCodeMsg(e.getStatus()));
            e.setConfirm(LogisticsOrderStatusEnum.WAIT_CONFIRMED.getCode().equals(e.getStatus()));
        });
        return Wrapper.success(pageData);
    }

    @Override
    public Wrapper<PageData<LogisticsOrderPlatformListResponse>> pagePlatformLogisticsOrder(LogisticsPlatformOrderListRequest request) {
        PageData<LogisticsOrderHandleListResponse> pageData = logisticsOrderQueryHelper.pagePlatformLogisticsOrder(request);

        List<LogisticsOrderPlatformListResponse> collect = pageData.getData().stream().map(e -> {
            LogisticsOrderPlatformListResponse response = new LogisticsOrderPlatformListResponse();
            response.setId(e.getId());
            response.setLogisticsOrderNo(e.getLogisticsOrderNo());
            response.setStatus(e.getStatus());
            response.setStatusName(LogisticsOrderStatusEnum.getCodeMsg(e.getStatus()));
            response.setRelevanceOrderCode(e.getRelevanceOrderCode());
            response.setCompanyName(e.getCompanyName());
            response.setShipperMemberName(e.getShipperMemberName());
            response.setReceiverMemberName(e.getReceiverMemberName());
            response.setCreateType(e.getCreateType());
            response.setInvoicesTime(e.getInvoicesTime());
            response.setTotalCarton(e.getTotalCarton());
            response.setTotalWeight(e.getTotalWeight());
            response.setTotalVolume(e.getTotalVolume());
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageData.getTotalCount(), collect));
    }

    @Override
    public Wrapper<LogisticsOrderResponse> getSupplierLogisticsOrder(OrderIdOrCodeRequest request, UserLoginCacheDTO loginUser) {
        LogisticsOrder logisticsOrder = logisticsOrderRepository.findOne((Specification<LogisticsOrder>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(cb.equal(root.get("memberId"), loginUser.getMemberId()));
            predicateList.add(cb.equal(root.get("roleId"), loginUser.getMemberRoleId()));
            if (Objects.nonNull(request.getId())) {
                predicateList.add(cb.equal(root.get("id"), request.getId()));
            } else {
                predicateList.add(cb.equal(root.get("logisticsOrderNo"), request.getCode()));
            }

            Predicate[] p = new Predicate[predicateList.size()];
            return query.where(predicateList.toArray(p)).getRestriction();
        }).orElse(null);

        if (Objects.isNull(logisticsOrder)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }

        // 查询订单详情
        LogisticsOrderResponse logisticsOrderResponse = getOrderDetail(logisticsOrder);

        return Wrapper.success(logisticsOrderResponse);
    }

    @Override
    public Wrapper<LogisticsOrderResponse> getHandleLogisticsOrder(OrderIdOrCodeRequest request, UserLoginCacheDTO loginUser) {
        LogisticsOrder logisticsOrder = logisticsOrderRepository.findOne((Specification<LogisticsOrder>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (Objects.nonNull(request.getId())) {
                predicateList.add(cb.equal(root.get("id"), request.getId()));
            } else {
                predicateList.add(cb.equal(root.get("logisticsOrderNo"), request.getCode()));
            }

            Predicate[] p = new Predicate[predicateList.size()];
            return query.where(predicateList.toArray(p)).getRestriction();
        }).orElse(null);

        if (Objects.isNull(logisticsOrder)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }

        Company company = companyRepository.findById(logisticsOrder.getCompanyId()).orElse(null);
        if (Objects.isNull(company)
                || !loginUser.getMemberId().equals(company.getCompanyMemberId())
                || !loginUser.getMemberRoleId().equals(company.getCompanyRoleId())) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }

        // 查询订单详情
        LogisticsOrderResponse logisticsOrderResponse = getOrderDetail(logisticsOrder);

        return Wrapper.success(logisticsOrderResponse);
    }

    @Override
    public Wrapper<LogisticsOrderResponse> getPlatformLogisticsOrder(CommonIdRequest request) {
        LogisticsOrder logisticsOrder = logisticsOrderRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(logisticsOrder)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }

        // 查询订单详情
        LogisticsOrderResponse logisticsOrderResponse = getOrderDetail(logisticsOrder);

        return Wrapper.success(logisticsOrderResponse);
    }

    /**
     * 获取订单详情
     * @param logisticsOrder 物流单
     * @return 返回结果
     */
    private LogisticsOrderResponse getOrderDetail(LogisticsOrder logisticsOrder) {
        LogisticsOrderResponse logisticsOrderResponse = new LogisticsOrderResponse();
        logisticsOrderResponse.setId(logisticsOrder.getId());
        logisticsOrderResponse.setLogisticsOrderNo(logisticsOrder.getLogisticsOrderNo());
        logisticsOrderResponse.setStatus(logisticsOrder.getStatus());
        logisticsOrderResponse.setStatusName(LogisticsOrderStatusEnum.getCodeMsg(logisticsOrder.getStatus()));
        logisticsOrderResponse.setDigest(logisticsOrder.getDigest());
        logisticsOrderResponse.setCompanyId(logisticsOrder.getCompanyId());
        logisticsOrderResponse.setCompanyName(logisticsOrder.getCompanyName());
        logisticsOrderResponse.setShipmentOrderId(logisticsOrder.getShipmentOrderId());
        logisticsOrderResponse.setShipmentOrderCode(logisticsOrder.getShipmentOrderCode());
        logisticsOrderResponse.setRelevanceType(logisticsOrder.getRelevanceType());
        logisticsOrderResponse.setRelevanceOrderId(logisticsOrder.getRelevanceOrderId());
        logisticsOrderResponse.setRelevanceOrderCode(logisticsOrder.getRelevanceOrderCode());
        // 发货方地址
        logisticsOrderResponse.setShipperAddressId(logisticsOrder.getShipperAddressId());
        logisticsOrderResponse.setShipperMemberId(logisticsOrder.getMemberId());
        logisticsOrderResponse.setShipperRoleId(logisticsOrder.getRoleId());
        logisticsOrderResponse.setShipperMemberName(logisticsOrder.getMemberName());
        logisticsOrderResponse.setShipperName(logisticsOrder.getShipperName());
        logisticsOrderResponse.setShipperPhone(logisticsOrder.getShipperPhone());
        logisticsOrderResponse.setShipperFullAddress(logisticsOrder.getShipperFullAddress());
        // 收货方地址
        logisticsOrderResponse.setReceiverAddressId(logisticsOrder.getReceiverAddressId());
        logisticsOrderResponse.setReceiverFullAddress(logisticsOrder.getReceiverFullAddress());
        logisticsOrderResponse.setReceiverMemberId(logisticsOrder.getReceiverMemberId());
        logisticsOrderResponse.setReceiverRoleId(logisticsOrder.getReceiverRoleId());
        logisticsOrderResponse.setReceiverMemberName(logisticsOrder.getReceiverMemberName());
        logisticsOrderResponse.setReceiverName(logisticsOrder.getReceiverName());
        logisticsOrderResponse.setReceiverPhone(logisticsOrder.getReceiverPhone());
        logisticsOrderResponse.setTotalCarton(logisticsOrder.getTotalCarton());
        logisticsOrderResponse.setTotalWeight(logisticsOrder.getTotalWeight());
        logisticsOrderResponse.setTotalVolume(logisticsOrder.getTotalVolume());
        logisticsOrderResponse.setFreightPrice(logisticsOrder.getFreightPrice());
        logisticsOrderResponse.setTaxInclusive(logisticsOrder.getTaxInclusive());
        logisticsOrderResponse.setTaxRate(logisticsOrder.getTaxRate());
        logisticsOrderResponse.setSettlementWay(logisticsOrder.getSettlementWay());
        // 单据时间(创建时间)
        logisticsOrderResponse.setInvoicesTime(logisticsOrder.getCreateTime());
        logisticsOrderResponse.setCreateType(logisticsOrder.getCreateType());

        // 查询订单明细
        List<LogisticsOrderDetail> detailList = logisticsOrderDetailRepository.findAllByOrderId(logisticsOrder.getId());
        List<LogisticsOrderResponse.LogisticsOrderDetailResponse> detailResponseList = detailList.stream().map(detail -> {
            LogisticsOrderResponse.LogisticsOrderDetailResponse detailResponse = new LogisticsOrderResponse.LogisticsOrderDetailResponse();
            detailResponse.setProductId(detail.getProductId());
            detailResponse.setProductName(detail.getProductName());
            detailResponse.setCategoryName(detail.getCategoryName());
            detailResponse.setBrandName(detail.getBrandName());
            detailResponse.setUnitName(detail.getUnitName());
            detailResponse.setAmount(detail.getAmount());
            detailResponse.setCarton(detail.getCarton());
            detailResponse.setWeight(detail.getWeight());
            detailResponse.setVolume(detail.getVolume());
            return detailResponse;
        }).collect(Collectors.toList());
        logisticsOrderResponse.setDetailList(detailResponseList);

        List<LogisticsOrderLog> logisticsOrderLogList = logisticsOrderLogRepository.findAllByOrderId(logisticsOrder.getId(), Sort.by("id"));
        List<LogisticsOrderResponse.LogisticsOrderLogResponse> logResponseList = logisticsOrderLogList.stream().map(e -> {
            LogisticsOrderResponse.LogisticsOrderLogResponse logisticsOrderLogResponse = new LogisticsOrderResponse.LogisticsOrderLogResponse();
            logisticsOrderLogResponse.setId(e.getId());
            logisticsOrderLogResponse.setCreateTime(e.getOperateTime());
            logisticsOrderLogResponse.setOperatorRoleName(e.getOperatorRoleName());
            logisticsOrderLogResponse.setStatus(e.getStatus());
            logisticsOrderLogResponse.setStatusName(e.getStatusName());
            logisticsOrderLogResponse.setOperation(e.getOperation());
            logisticsOrderLogResponse.setRemark(e.getRemark());
            return logisticsOrderLogResponse;
        }).collect(Collectors.toList());

        InternalProcessQueryVO queryVO = new InternalProcessQueryVO();
        queryVO.setProcessKey(Constants.Workflow.key);
        queryVO.setMemberId(logisticsOrder.getMemberId());
        queryVO.setTaskId(logisticsOrder.getTaskId());

        Company company = companyRepository.findById(logisticsOrder.getCompanyId()).orElse(null);
        if (Objects.isNull(company)) {
            log.error("查询物流详情, 未找到物流服务商");
            return logisticsOrderResponse;
        }
        Wrapper<SimpleProcessDefVO> result = logisticsOrderWorkFlowService.listExternalProcessSteps(logisticsOrder.getRoleId(), company.getCompanyRoleId(), Constants.Workflow.key, logisticsOrder.getTaskId());
        if (result.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("查询物流详情, 调用工作流服务失败, message: {}", result.getMessage());
            return logisticsOrderResponse;
        }

        List<LogisticsOrderResponse.LogisticsOrderExternalResponse> externalResponseList = result.getData().getTasks().stream().map(task -> {
            LogisticsOrderResponse.LogisticsOrderExternalResponse logisticsOrderExternalResponse = new LogisticsOrderResponse.LogisticsOrderExternalResponse();
            logisticsOrderExternalResponse.setStep(task.getTaskStep());
            logisticsOrderExternalResponse.setStepName(task.getTaskName());
            logisticsOrderExternalResponse.setRoleName(task.getRoleName());
            // 任务执行完毕, 且状态为接受
            if (StringUtils.isBlank(logisticsOrder.getTaskId()) && LogisticsOrderStatusEnum.RECEIVE.getCode().equals(logisticsOrder.getStatus())) {
                logisticsOrderExternalResponse.setIsExecute(CommonBooleanEnum.YES.getCode());
            } else {
                logisticsOrderExternalResponse.setIsExecute(result.getData().getCurrentStep() >= task.getTaskStep() ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode());
            }

            return logisticsOrderExternalResponse;
        }).sorted(Comparator.comparingInt(LogisticsOrderResponse.LogisticsOrderExternalResponse::getStep)).collect(Collectors.toList());

        logisticsOrderResponse.setExternalList(externalResponseList);
        logisticsOrderResponse.setLogisticsOrderLogList(logResponseList);

        return logisticsOrderResponse;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> addLogisticsOrder(LogisticsOrderRequest request, UserLoginCacheDTO loginUser) {
        // 物流单信息
        LogisticsOrder logisticsOrder = new LogisticsOrder();
        logisticsOrder.setDigest(request.getDigest());
        logisticsOrder.setShipmentOrderId(request.getShipmentOrderId());
        logisticsOrder.setShipmentOrderCode(request.getShipmentOrderCode());
        logisticsOrder.setRelevanceOrderId(request.getRelevanceOrderId());
        logisticsOrder.setRelevanceOrderCode(request.getRelevanceOrderCode());
        logisticsOrder.setRelevanceType(request.getRelevanceType());
        // 发货方
        logisticsOrder.setMemberId(loginUser.getMemberId());
        logisticsOrder.setRoleId(loginUser.getMemberRoleId());
        logisticsOrder.setMemberName(loginUser.getCompany());
        logisticsOrder.setShipperName(request.getShipperName());
        logisticsOrder.setShipperPhone(request.getShipperPhone());
        logisticsOrder.setShipperAddressId(request.getShipperAddressId());
        logisticsOrder.setShipperFullAddress(request.getShipperFullAddress());
        // 收货方
        logisticsOrder.setReceiverMemberId(request.getReceiverMemberId());
        logisticsOrder.setReceiverRoleId(request.getReceiverRoleId());
        logisticsOrder.setReceiverMemberName(request.getReceiverMemberName());
        logisticsOrder.setReceiverName(request.getReceiverName());
        logisticsOrder.setReceiverPhone(request.getReceiverPhone());
        logisticsOrder.setReceiverAddressId(request.getReceiverAddressId());
        logisticsOrder.setReceiverFullAddress(request.getReceiverFullAddress());
        // 物流公司
        logisticsOrder.setCompanyId(request.getCompanyId());
        logisticsOrder.setCompanyName(request.getCompanyName());
        // 创建类型
        logisticsOrder.setCreateType(request.getCreateType());
        logisticsOrder.setSettlementWay(request.getSettlementWay());
        logisticsOrder.setCreateTime(System.currentTimeMillis());

        // 计算运费,总数量,总重量,总体积
        List<LogisticsOrderRequest.LogisticsOrderDetailRequest> detailList = request.getDetailList();
        handleOrderRequest(detailList, logisticsOrder);
        // 保存
        logisticsOrderRepository.saveAndFlush(logisticsOrder);

        // 更订单编号
        String orderNo = CodeUtils.digits32(logisticsOrder.getId(), 6);
        logisticsOrder.setLogisticsOrderNo(Constants.Order.ORDER_NO_PREFIX + orderNo);
        logisticsOrderRepository.saveAndFlush(logisticsOrder);

        // 保存关联的订单明细
        saveAllLogisticsOrderDetail(detailList, logisticsOrder.getId());

        // 创建类型处理
        if (LogisticsOrderCreateTypeEnum.LOGISTICS.getCode().equals(request.getCreateType())) {
            // 开始工作流
            Wrapper<SimpleTaskCompleteVO> taskResult = logisticsOrderWorkFlowService.startTaskProcess(logisticsOrder, loginUser);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                log.error("物流单待提交 - 请求工作流: " + taskResult.getMessage());
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 更新物流单状态
            logisticsOrder.setStatus(taskResult.getData().getStatus());
            logisticsOrder.setTaskId(taskResult.getData().getTaskId());
            logisticsOrderRepository.saveAndFlush(logisticsOrder);

            // 物流单创建首页统计
            reportService.createOperateNotice(logisticsOrder);

        } else if (LogisticsOrderCreateTypeEnum.SALES_ORDER.getCode().equals(request.getCreateType())) {
            // 开始工作流并执行第一步
            Wrapper<SimpleTaskCompleteVO> taskResult = logisticsOrderWorkFlowService.startThenCompleteTaskProcess(logisticsOrder, loginUser);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                log.error("物流单提交 - 请求工作流: " + taskResult.getMessage());
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 更新物流单状态
            logisticsOrder.setTaskId(taskResult.getData().getTaskId());
            logisticsOrder.setStatus(taskResult.getData().getStatus());
            logisticsOrderRepository.saveAndFlush(logisticsOrder);

            // 新增物流单同步销售数据
            Wrapper<?> wrapper = syncDataService.addLogisticsSyncDataSales(logisticsOrder);
            if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                log.error("订单新增物流单: " + wrapper.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_ORDER_ERROR);
            }

            // 物流单提交(其他单据)首页统计
            reportService.submitOtherOperateNotice(logisticsOrder);

            // 物流单提交消息通知
            notifyService.submitMessage(logisticsOrder);
        } else if (LogisticsOrderCreateTypeEnum.PRODUCTION_NOTIFY.getCode().equals(request.getCreateType())) {
            // 开始工作流并执行第一步
            Wrapper<SimpleTaskCompleteVO> taskResult = logisticsOrderWorkFlowService.startThenCompleteTaskProcess(logisticsOrder, loginUser);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                log.error("物流单提交 - 请求工作流: " + taskResult.getMessage());
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 更新物流单状态
            logisticsOrder.setTaskId(taskResult.getData().getTaskId());
            logisticsOrder.setStatus(taskResult.getData().getStatus());
            logisticsOrderRepository.saveAndFlush(logisticsOrder);

            // 新增物流单同步加工数据
            Wrapper<?> wrapper = syncDataService.addLogisticsSyncDataProduction(logisticsOrder);
            if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                log.error("生产通知单新增物流单: " + wrapper.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_ENHANCE_ERROR);
            }

            // 物流单提交(其他单据)首页统计
            reportService.submitOtherOperateNotice(logisticsOrder);

            // 物流单提交消息通知
            notifyService.submitMessage(logisticsOrder);
        } else if (LogisticsOrderCreateTypeEnum.REPLACE_RETURN.getCode().equals(request.getCreateType())) {
            // 开始工作流并执行第一步
            Wrapper<SimpleTaskCompleteVO> taskResult = logisticsOrderWorkFlowService.startThenCompleteTaskProcess(logisticsOrder, loginUser);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                log.error("物流单提交 - 请求工作流: " + taskResult.getMessage());
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 更新物流单状态
            logisticsOrder.setTaskId(taskResult.getData().getTaskId());
            logisticsOrder.setStatus(taskResult.getData().getStatus());
            logisticsOrderRepository.saveAndFlush(logisticsOrder);

            // 新增物流单同步换货(退货发货)数据
            Wrapper<?> wrapper = syncDataService.addLogisticsSyncDataReplaceReturn(loginUser, logisticsOrder);
            if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                log.error("换货(退货发货)新增物流单: " + wrapper.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_AFTER_SALE_ERROR);
            }

            // 物流单提交(其他单据)首页统计
            reportService.submitOtherOperateNotice(logisticsOrder);

            // 物流单提交消息通知
            notifyService.submitMessage(logisticsOrder);
        } else if (LogisticsOrderCreateTypeEnum.REPLACE_REPLACE.getCode().equals(request.getCreateType())) {
            // 开始工作流并执行第一步
            Wrapper<SimpleTaskCompleteVO> taskResult = logisticsOrderWorkFlowService.startThenCompleteTaskProcess(logisticsOrder, loginUser);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                log.error("物流单提交 - 请求工作流: " + taskResult.getMessage());
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 更新物流单状态
            logisticsOrder.setTaskId(taskResult.getData().getTaskId());
            logisticsOrder.setStatus(taskResult.getData().getStatus());
            logisticsOrderRepository.saveAndFlush(logisticsOrder);

            // 新增物流单同步换货(换货发货)数据
            Wrapper<?> wrapper = syncDataService.addLogisticsSyncDataReplaceReplace(loginUser, logisticsOrder);
            if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                log.error("换货(换货发货)新增物流单: " + wrapper.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_AFTER_SALE_ERROR);
            }

            // 物流单提交(其他单据)首页统计
            reportService.submitOtherOperateNotice(logisticsOrder);

            // 物流单提交消息通知
            notifyService.submitMessage(logisticsOrder);
        } else if (LogisticsOrderCreateTypeEnum.RETURN_RETURN.getCode().equals(request.getCreateType())) {
            // 开始工作流并执行第一步
            Wrapper<SimpleTaskCompleteVO> taskResult = logisticsOrderWorkFlowService.startThenCompleteTaskProcess(logisticsOrder, loginUser);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                log.error("物流单提交 - 请求工作流: " + taskResult.getMessage());
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 更新物流单状态
            logisticsOrder.setTaskId(taskResult.getData().getTaskId());
            logisticsOrder.setStatus(taskResult.getData().getStatus());
            logisticsOrderRepository.saveAndFlush(logisticsOrder);

            // 新增物流单同步退货(退货发货)数据
            Wrapper<?> wrapper = syncDataService.addLogisticsSyncDataReturnReturn(loginUser, logisticsOrder);
            if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                log.error("退货(退货发货)新增物流单: " + wrapper.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_AFTER_SALE_ERROR);
            }

            // 物流单提交(其他单据)首页统计
            reportService.submitOtherOperateNotice(logisticsOrder);

            // 物流单提交消息通知
            notifyService.submitMessage(logisticsOrder);
        }

        return Wrapper.success();
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> updateLogisticsOrder(LogisticsOrderRequest request, UserLoginCacheDTO loginUser) {
        LogisticsOrder logisticsOrder = logisticsOrderRepository.findByIdAndMemberIdAndRoleId(request.getId(), loginUser.getMemberId(), loginUser.getMemberRoleId());
        if (Objects.isNull(logisticsOrder)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }
        // 数据状态只能为待提交或不接受
        List<Integer> statusList = Arrays.asList(LogisticsOrderStatusEnum.WAIT_SUBMIT.getCode(), LogisticsOrderStatusEnum.NO_RECEIVE.getCode());
        if (!statusList.contains(logisticsOrder.getStatus())) {
            return Wrapper.fail(ResponseCode.LS_PARAM_STATUS_INCORRECT);
        }

        logisticsOrder.setDigest(request.getDigest());
        logisticsOrder.setShipmentOrderId(request.getShipmentOrderId());
        logisticsOrder.setShipmentOrderCode(request.getShipmentOrderCode());
        logisticsOrder.setRelevanceOrderId(request.getRelevanceOrderId());
        logisticsOrder.setRelevanceOrderCode(request.getRelevanceOrderCode());
        logisticsOrder.setReceiverAddressId(request.getReceiverAddressId());
        logisticsOrder.setReceiverName(request.getReceiverName());
        logisticsOrder.setReceiverPhone(request.getReceiverPhone());
        logisticsOrder.setReceiverFullAddress(request.getReceiverFullAddress());
        // 物流公司
        logisticsOrder.setCompanyId(request.getCompanyId());
        logisticsOrder.setCompanyName(request.getCompanyName());

        // 计算运费,总数量,总重量,总体积
        List<LogisticsOrderRequest.LogisticsOrderDetailRequest> detailList = request.getDetailList();
        handleOrderRequest(detailList, logisticsOrder);

        // 不接受修改后状态为待确认(涉及其他流程:如订单流程创建物流单等等, 在他们的流程中[不接受]状态修改后为[待确认]状态),所以处逻辑为修改后直接提交给物流服务商审核
        if (LogisticsOrderStatusEnum.NO_RECEIVE.getCode().equals(logisticsOrder.getStatus())) {
            // 执行工作流
            Wrapper<SimpleTaskCompleteVO> taskResult = logisticsOrderWorkFlowService.completeTask(logisticsOrder, ProcessTaskStatusEnum.GOTO_NEXT_STEP.getCode());
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                log.error("物流单提交 - 请求工作流: " + taskResult.getMessage());
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            // 更新物流单状态
            logisticsOrder.setTaskId(taskResult.getData().getTaskId());
            logisticsOrder.setStatus(taskResult.getData().getStatus());
            logisticsOrderRepository.saveAndFlush(logisticsOrder);

            // 删除关联的订单明细
            logisticsOrderDetailRepository.deleteByOrderId(logisticsOrder.getId());

            // 保存关联的订单明细
            saveAllLogisticsOrderDetail(request.getDetailList(), logisticsOrder.getId());

            // 添加历史流转记录
            String oper = taskResult.getData().getProperties().getOrDefault("oper", "");
            logisticsOrderLogService.createSubmitLogisticsOrderLog(logisticsOrder.getId(), taskResult.getData().getStatus(),  oper, loginUser);

            // 同步对应单状态
            if (LogisticsOrderCreateTypeEnum.SALES_ORDER.getCode().equals(logisticsOrder.getCreateType())) {
                // 确认物流单同步销售数据
                Wrapper<?> wrapper = syncDataService.confirmLogisticsSyncDataSales(loginUser, logisticsOrder, OrderLogisticsTypeEnum.TO_CONFIRM.getCode());
                if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                    log.error("订单提交物流单: " + wrapper.getMessage());
                    throw new BusinessException(ResponseCode.SERVICE_ORDER_ERROR);
                }
            } else if (LogisticsOrderCreateTypeEnum.PRODUCTION_NOTIFY.getCode().equals(logisticsOrder.getCreateType())) {
                // 确认物流单同步加工数据
                Wrapper<?> wrapper = syncDataService.confirmLogisticsSyncDataProduction(loginUser, logisticsOrder, OrderLogisticsTypeEnum.TO_CONFIRM.getCode());
                if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                    log.error("生产通知单提交物流单: " + wrapper.getMessage());
                    throw new BusinessException(ResponseCode.SERVICE_ENHANCE_ERROR);
                }
            } else if (LogisticsOrderCreateTypeEnum.REPLACE_RETURN.getCode().equals(logisticsOrder.getCreateType())) {
                // 确认物流单同步换货(退货发货)数据
                Wrapper<?> wrapper = syncDataService.confirmLogisticsSyncDataReplaceReturn(loginUser, logisticsOrder, OrderLogisticsTypeEnum.TO_CONFIRM.getCode());
                if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                    log.error("换货退货提交物流单: " + wrapper.getMessage());
                    throw new BusinessException(ResponseCode.SERVICE_AFTER_SALE_ERROR);
                }
            } else if (LogisticsOrderCreateTypeEnum.REPLACE_REPLACE.getCode().equals(logisticsOrder.getCreateType())) {
                // 确认物流单同步换货(换货发货)数据
                Wrapper<?> wrapper = syncDataService.confirmLogisticsSyncDataReplaceReplace(loginUser, logisticsOrder, OrderLogisticsTypeEnum.TO_CONFIRM.getCode());
                if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                    log.error("换货发货提交物流单: " + wrapper.getMessage());
                    throw new BusinessException(ResponseCode.SERVICE_AFTER_SALE_ERROR);
                }
            } else if (LogisticsOrderCreateTypeEnum.RETURN_RETURN.getCode().equals(logisticsOrder.getCreateType())) {
                // 确认物流单同步退货(退货发货)数据
                Wrapper<?> wrapper = syncDataService.confirmLogisticsSyncDataReturnReturn(loginUser, logisticsOrder, OrderLogisticsTypeEnum.TO_CONFIRM.getCode());
                if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                    log.error("退货发货提交物流单: " + wrapper.getMessage());
                    throw new BusinessException(ResponseCode.SERVICE_AFTER_SALE_ERROR);
                }
            }

            // 物流单提交(正常)首页统计
            reportService.submitNormalOperateNotice(logisticsOrder);

            // 物流单提交消息通知
            notifyService.submitMessage(logisticsOrder);
        } else {
            // 待提交修改不需执行工作流
            logisticsOrderRepository.saveAndFlush(logisticsOrder);

            // 删除关联的订单明细
            logisticsOrderDetailRepository.deleteByOrderId(logisticsOrder.getId());

            // 保存关联的订单明细
            saveAllLogisticsOrderDetail(request.getDetailList(), logisticsOrder.getId());
        }

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> deleteLogisticsOrder(CommonIdRequest request, UserLoginCacheDTO loginUser) {
        LogisticsOrder logisticsOrder = logisticsOrderRepository.findByIdAndMemberIdAndRoleId(request.getId(), loginUser.getMemberId(), loginUser.getMemberRoleId());
        if (Objects.isNull(logisticsOrder)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }
        // 只能状态为待提交的订单
        if (!LogisticsOrderStatusEnum.WAIT_SUBMIT.getCode().equals(logisticsOrder.getStatus())) {
            return Wrapper.fail(ResponseCode.LS_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        // 不能删除已进入工作流的订单
        List<LogisticsOrderLog> logisticsOrderLogList = logisticsOrderLogRepository.findAllByOrderId(request.getId());
        for (LogisticsOrderLog logisticsOrderLog : logisticsOrderLogList) {
            if (LogisticsOrderStatusEnum.WAIT_CONFIRMED.getCode().equals(logisticsOrderLog.getStatus())) {
                return Wrapper.fail(ResponseCode.LS_TASK_ENTER_NOT_DEL);
            }
        }

        logisticsOrderRepository.deleteById(logisticsOrder.getId());

        // 删除关联的订单明细
        logisticsOrderDetailRepository.deleteByOrderId(logisticsOrder.getId());

        // 物流单删除首页统计
        reportService.deleteOperateNotice(logisticsOrder);

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> updateOrderStatusSubmit(CommonIdRequest request, UserLoginCacheDTO loginUser) {
        LogisticsOrder logisticsOrder = logisticsOrderRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(logisticsOrder)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }
        // 数据状态应为待提交
        if (!LogisticsOrderStatusEnum.WAIT_SUBMIT.getCode().equals(logisticsOrder.getStatus())) {
            return Wrapper.fail(ResponseCode.LS_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        // 执行工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = logisticsOrderWorkFlowService.completeTask(logisticsOrder, ProcessTaskStatusEnum.GOTO_NEXT_STEP.getCode());
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            log.error("物流单提交 - 请求工作流: " + taskResult.getMessage());
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        // 更新物流单状态
        logisticsOrder.setTaskId(taskResult.getData().getTaskId());
        logisticsOrder.setStatus(taskResult.getData().getStatus());
        logisticsOrderRepository.saveAndFlush(logisticsOrder);

        // 添加历史流转记录
        String oper = taskResult.getData().getProperties().getOrDefault("oper", "");
        logisticsOrderLogService.createSubmitLogisticsOrderLog(logisticsOrder.getId(), taskResult.getData().getStatus(),  oper, loginUser);

        // 物流单提交(正常)首页统计
        reportService.submitNormalOperateNotice(logisticsOrder);

        // 物流单提交消息通知
        notifyService.submitMessage(logisticsOrder);


        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> updateOrderStatusConfirm(LogisticsOrderConfirmRequest request, UserLoginCacheDTO loginUser) {
        LogisticsOrder logisticsOrder = logisticsOrderRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(logisticsOrder)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }
        // 请求只能为接受或不接受
        List<Integer> auditStatusList = Arrays.asList(LogisticsOrderStatusEnum.NO_RECEIVE.getCode(), LogisticsOrderStatusEnum.RECEIVE.getCode());
        if (!auditStatusList.contains(request.getStatus())) {
            return Wrapper.fail(ResponseCode.LS_PARAM_STATUS_INCORRECT);
        }
        // 数据状态应为待确认
        if (!LogisticsOrderStatusEnum.WAIT_CONFIRMED.getCode().equals(logisticsOrder.getStatus())) {
            return Wrapper.fail(ResponseCode.LS_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        // 物流公司是当前用户
        Company company = companyRepository.findById(logisticsOrder.getCompanyId()).orElse(null);
        if (Objects.isNull(company)
                || !loginUser.getMemberId().equals(company.getCompanyMemberId())
                || !loginUser.getMemberRoleId().equals(company.getCompanyRoleId())) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }

        // 执行工作流
        Integer agree = LogisticsOrderStatusEnum.RECEIVE.getCode().equals(request.getStatus()) ?
                ProcessTaskStatusEnum.AGREE.getCode() : ProcessTaskStatusEnum.DISAGREE.getCode();

        Wrapper<SimpleTaskCompleteVO> taskResult = logisticsOrderWorkFlowService.completeTask(logisticsOrder, agree);
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            log.error("物流单确认 - 请求工作流: " + taskResult.getMessage());
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        // 更新物流单状态
        logisticsOrder.setTaskId(taskResult.getData().getTaskId());
        logisticsOrder.setStatus(taskResult.getData().getStatus());
        // 确认时间
        logisticsOrder.setConfirmTime(LogisticsOrderStatusEnum.RECEIVE.getCode().equals(request.getStatus()) ? System.currentTimeMillis() : null);
        // 运费
        logisticsOrder.setFreightPrice(Objects.isNull(request.getFreightPrice()) ? BigDecimal.ZERO : request.getFreightPrice());
        // 税率
        logisticsOrder.setTaxInclusive(request.getTaxInclusive());
        logisticsOrder.setTaxRate(CommonBooleanEnum.YES.getCode().equals(request.getTaxInclusive()) ? request.getTaxRate() : 0D);

        logisticsOrderRepository.saveAndFlush(logisticsOrder);

        // 添加历史流转记录
        String oper = taskResult.getData().getProperties().getOrDefault("oper", "");
        logisticsOrderLogService.createConfirmLogisticsOrderLog(logisticsOrder.getId(), taskResult.getData().getStatus(),  oper, request.getRemark(), loginUser);

        Integer callStatus = LogisticsOrderStatusEnum.RECEIVE.getCode().equals(request.getStatus()) ? OrderLogisticsTypeEnum.ACCEPT.getCode() : OrderLogisticsTypeEnum.NOT_ACCEPT.getCode();
        if (LogisticsOrderCreateTypeEnum.SALES_ORDER.getCode().equals(logisticsOrder.getCreateType())) {
            // 确认物流单同步销售数据
            Wrapper<?> wrapper = syncDataService.confirmLogisticsSyncDataSales(loginUser, logisticsOrder, callStatus);
            if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                log.error("订单确认物流单: " + wrapper.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_ORDER_ERROR);
            }
        } else if (LogisticsOrderCreateTypeEnum.PRODUCTION_NOTIFY.getCode().equals(logisticsOrder.getCreateType())) {
            // 确认物流单同步加工数据
            Wrapper<?> wrapper = syncDataService.confirmLogisticsSyncDataProduction(loginUser, logisticsOrder, callStatus);
            if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                log.error("生产通知单确认物流单: " + wrapper.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_ENHANCE_ERROR);
            }
        } else if (LogisticsOrderCreateTypeEnum.REPLACE_RETURN.getCode().equals(logisticsOrder.getCreateType())) {
            // 确认物流单同步换货(退货发货)数据
            Wrapper<?> wrapper = syncDataService.confirmLogisticsSyncDataReplaceReturn(loginUser, logisticsOrder, callStatus);
            if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                log.error("换货退货确认物流单: " + wrapper.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_AFTER_SALE_ERROR);
            }
        } else if (LogisticsOrderCreateTypeEnum.REPLACE_REPLACE.getCode().equals(logisticsOrder.getCreateType())) {
            // 确认物流单同步换货(换货发货)数据
            Wrapper<?> wrapper = syncDataService.confirmLogisticsSyncDataReplaceReplace(loginUser, logisticsOrder, callStatus);
            if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                log.error("换货发货确认物流单: " + wrapper.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_AFTER_SALE_ERROR);
            }
        } else if (LogisticsOrderCreateTypeEnum.RETURN_RETURN.getCode().equals(logisticsOrder.getCreateType())) {
            // 确认物流单同步退货(退货发货)数据
            Wrapper<?> wrapper = syncDataService.confirmLogisticsSyncDataReturnReturn(loginUser, logisticsOrder, callStatus);
            if (ResponseCode.SUCCESS.getCode() != wrapper.getCode()) {
                log.error("退货发货确认物流单: " + wrapper.getMessage());
                throw new BusinessException(ResponseCode.SERVICE_AFTER_SALE_ERROR);
            }
        }

        // 物流单确认首页统计
        reportService.confirmOperateNotice(logisticsOrder);

        // 物流单确认消息通知
        notifyService.confirmMessage(logisticsOrder, request.getStatus());

        return Wrapper.success();
    }

    @Override
    public Wrapper<List<StatusVO>> listLogisticsOrderStatus() {
        List<StatusVO> statusVOList = Stream.of(LogisticsOrderStatusEnum.values()).map(e -> {
            StatusVO statusVO = new StatusVO();
            statusVO.setCode(e.getCode());
            statusVO.setMessage(e.getMessage());
            return statusVO;
        }).collect(Collectors.toList());

        return Wrapper.success(statusVOList);
    }

    private void saveAllLogisticsOrderDetail(List<LogisticsOrderRequest.LogisticsOrderDetailRequest> orderDetailList,
                                             Long orderId) {
        if (!CollectionUtils.isEmpty(orderDetailList)) {
            List<LogisticsOrderDetail> saveList = orderDetailList.stream().map(e -> {
                LogisticsOrderDetail orderDetail = new LogisticsOrderDetail();
                orderDetail.setOrderId(orderId);
                orderDetail.setProductId(e.getProductId());
                orderDetail.setProductName(e.getProductName());
                orderDetail.setCategoryName(e.getCategoryName());
                orderDetail.setBrandName(e.getBrandName());
                orderDetail.setUnitName(e.getUnitName());
                orderDetail.setAmount(e.getAmount());
                orderDetail.setCarton(e.getCarton());
                orderDetail.setWeight(e.getWeight());
                orderDetail.setVolume(e.getVolume());
                return orderDetail;
            }).collect(Collectors.toList());

            logisticsOrderDetailRepository.saveAll(saveList);
        }
    }

    private void handleOrderRequest(List<LogisticsOrderRequest.LogisticsOrderDetailRequest> orderDetailList,
                                    LogisticsOrder logisticsOrder) {
        BigDecimal cartonSum = BigDecimal.ZERO;
        BigDecimal weightSum = BigDecimal.ZERO;
        BigDecimal volumeSum = BigDecimal.ZERO;

        for (LogisticsOrderRequest.LogisticsOrderDetailRequest detail : orderDetailList) {
            cartonSum = cartonSum.add(BigDecimal.valueOf(detail.getCarton()));
            weightSum = weightSum.add(BigDecimal.valueOf(detail.getWeight()));
            volumeSum = volumeSum.add(BigDecimal.valueOf(detail.getVolume()));
        }

        cartonSum = cartonSum.setScale(1, BigDecimal.ROUND_DOWN);
        weightSum = weightSum.setScale(3, BigDecimal.ROUND_DOWN);
        volumeSum = volumeSum.setScale(3, BigDecimal.ROUND_DOWN);

        logisticsOrder.setTotalCarton(cartonSum.doubleValue());
        logisticsOrder.setTotalWeight(weightSum.doubleValue());
        logisticsOrder.setTotalVolume(volumeSum.doubleValue());
    }
}
